package com.github.soiff.port;

import java.io.IOException;
import java.net.ServerSocket;

import static java.lang.Math.abs;

/**
 * Created by z0228 on 2017/1/1.
 * An implementation for TODO:
 *
 * @author : z0228
 * @version : 1.0
 * @since : 1.8
 */
public class FreePortDetection {
    private static final int MIN = 1024;
    private static final int MAX = 65535;
    private static final int INC = 30;
    private static final int ILEN = MAX - MIN;

    private static int hash(String... args) {
        StringBuilder sb = new StringBuilder();
        if (null != args) {
            for (String arg : args)
                sb.append(':').append(arg);
        }
        return sb.toString().hashCode();
    }

    private static int start = -1;
    private static int valid0 = -1;
    private static int valid1 = -1;

    private static int next(int value) {
        int next;
        if (-1 == start || -1 == valid0 || -1 == valid1) {
            start = MIN + abs(value) % ILEN;
            if (start + INC >= MAX) {
                valid0 = start - INC + 1;
                valid1 = start - 1;
            } else {
                valid0 = start + 1;
                valid1 = start + INC - 1;
            }
            next = start;
        } else {
            next = value + INC;
        }
        if (next >= MAX)
            next = MIN + next - MAX;
        if (valid0 <= next && next <= valid1)
            return -1;
        return next;
    }

    public static void main(String[] args) {
        int port = next(hash(args));
        ServerSocket ss;
        while (port > 0) {
            try {
                ss = new ServerSocket(port);
                System.out.println(ss.getLocalPort());
                ss.close();
                break;
            } catch (IOException ignored) {
            }
            port = next(port);
        }
    }
}
